GetX update 原理

2023-09-08
  1. get_state.dart

GetBuilder 是继承自 StatefulWidget 的,其对应的 State 是 GetBuilderState,在 initState 方法最后会调用 _subscribeToController,并向 controller 中添加 listener,用于刷新 UI:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/// Register to listen Controller's events.
/// It gets a reference to the remove() callback, to delete the
/// setState "link" from the Controller.
void _subscribeToController() {
_remove?.call();
_remove = (widget.id == null)
? controller?.addListener(
_filter != null ? _filterUpdate : getUpdate,
)
: controller?.addListenerId(
widget.id,
_filter != null ? _filterUpdate : getUpdate,
);
}

void _filterUpdate() {
var newFilter = widget.filter!(controller!);
if (newFilter != _filter) {
_filter = newFilter;
getUpdate();
}
}

/// Experimental method to replace setState((){});
/// Used with GetStateUpdate.
void getUpdate() {
if (mounted) setState(() {});
}

这里的 controller 是在 initState 中通过 GetInstance().find 取得或通过 GetBuilder 的 init 参数指定的,是 GetxController 的子类。

  1. get_controllers.dart

我们看下 GetxController:

1
2
3
4
abstract class GetxController extends DisposableInterface
with ListenableMixin, ListNotifierMixin {
...
}

GetxController 混入了 ListNotifierMixin,而 addListener 和 addListenerId 正是 ListNotifierMixin 中的方法。

  1. list_notifier.dart

再查看 ListNotifierMixin,内部持有 _updaters 和 _updatersGroupIds,上面 _subscribeToController 中添加的 listener 最终都保存在了 _updaters 或者 _updatersGroupIds 中。

  1. get_controllers.dart

调用 update 的时候,如果指定了 ids,就会遍历 id 去 _updatersGroupIds 中查找匹配的 listener 并 call,如果没有指定 ids,则会调用 refresh 方法,refresh 会调用 _notifyUpdate 方法,遍历 _updaters 中的 listener 并 call,最后都是触发 setState。

以上基于 get 4.6.5 版本。